#pragma once
#include<memory>
#include<atomic>
#include<mutex>
#include<map>
#include<vector>
#include<queue>
#include<thread>
#include<future>
#include<algorithm>
#include<queue>
#include<chrono>
#include<functional>
#include<iostream>
#include<sstream>
#include<sstream>
#include<fstream>
#include<string>
#include<exception>
#include<cmath>
#include<array>
#include<any>
#ifdef _WIN32
#include <execution>
#endif
#include <cstdlib>
#ifdef __cpp_lib_shared_mutex
#include<shared_mutex>
#else
#define unlock_shared unlock
#define lock_shared lock
#endif
#ifdef _WIN32
#include<Windows.h>
#define DLL_EXPORT __declspec(dllexport)
#define DLL_EXPORT_EX __declspec(dllexport)

#else
#ifdef __linux__
#include <dlfcn.h>
#include <unistd.h> 

#define DLL_EXPORT __attribute__((visibility("default"),noinline))
#define DLL_EXPORT_EX __attribute__((visibility("default"),noinline,optimize("O0")))

#endif
#endif

//JoyEngine运行时核心的版本号标识（宏定义）
#define ECS_CORE_VERSION (0xD1050402)


//JoyEngine运行时核心的根命名空间（命名空间）
namespace ecs
{
	//预留的无用类，不允许实现这个类（类）
	class JoyEngineNullNameUnusedName;
	struct JoyEngineNullNameUnusedNameStruct;

	//预留的最高权限的类，这个类内的操作不受访问权限约束，这个类并没有被实际定义（类）
	class HIGHEST_PROMISSION;

	//各种规范化的类型存在于此命名空间（命名空间）
	namespace Type
	{
		template<typename ... T>
		using Function=std::function<T...>;

		//弱类型对象，可以接收一切类型的值（至少满足可移动构造）（类型）
		using Any = std::any;

		template<typename ... T>
		using Atomic=std::atomic<T...>;

		//递归锁类型，在一个线程内不会发生重复加锁的锁（类型）
		using Lock = std::recursive_mutex;

		//表示大小的类型，在x86下等同于unsigned int, x64下等同于unsigned long long（类型）
		using Size = size_t;

		//有符号整数类型，可以表达的范围在-2147483648~2147483647（类型）
		using Int = int;

		//无符号整数类型，可以表达的范围在0~4294967295（类型）
		using UInt = unsigned int;

		//单精度浮点数类型（类型）
		using Float = float;

		//双精度浮点数类型（类型）
		using Double = double;

		//有符号长整数类型，可以表达的范围在-9223372036854775808~9223372036854775807（类型）
		using Long = long long;

		//长双精度浮点数类型（类型）
		using LongDouble = long double;

		//非线程安全的动态数组（类型）
		template<typename V>
		using NotSafeVector = std::vector< V>;


		struct ListEnd {};

		template<typename T, typename ...Ts>
		class ___ComponentList
		{

			template<typename TA>
			struct decRef
			{
				using type = TA;
			};
			template<typename TA>
			struct decRef<TA&>
			{
				using type = TA;
			};

			struct ComponentListBase { char name; };



			template<typename F, typename Tsa>
			static F& getComponentinList(typename Tsa::Type& List);
		public:
			using Type = struct :public ___ComponentList<Ts...>::Type
			{
				T name;
			};
			using FirstType = T;
			using SecondType = typename  ___ComponentList<Ts...>::Type;
			using Second = ___ComponentList<Ts...>;
		private:
			Type Member;
		public:
			template<typename F>
			F& getMember()
			{
				return getComponentinList<F, typename decRef<decltype(*this)>::type>(Member);
			}
		};
		template<>
		class ___ComponentList<ListEnd>
		{
		public:
			struct ComponentListBase { char name; };
			using Type = ComponentListBase;
			using FirstType = ComponentListBase;
			using SecondType = ComponentListBase;
			using Second = ___ComponentList<ListEnd>;
		};
		template<typename T, typename ... Ts>
		template<typename F, typename Tsa>
		inline F& ___ComponentList<T, Ts...>::getComponentinList(typename Tsa::Type& List)
		{
			if (std::is_same<___ComponentList<ListEnd>::ComponentListBase, typename Tsa::FirstType>::value)
				return *(F*)nullptr;
			else if (std::is_same<F, typename Tsa::FirstType>::value)
				return *(F*)& List.name;
			return getComponentinList<F, typename Tsa::Second>((typename Tsa::SecondType&)List);
		}

		template< typename ...Ts>
		using ComponentList = ___ComponentList<Ts..., ListEnd>;

#ifdef __cpp_lib_shared_mutex
		using SharedMutex = std::shared_mutex;
		template<typename V>
		using SharedLock = std::shared_lock<V>;
#else
		using SharedMutex = std::mutex;
		template<typename V>
		using SharedLock = std::lock_guard<V>;
#endif
		template<class T>
		std::vector<T> operator && (std::vector<T> a, std::vector<T> b)
		{
			using namespace std;
			std::vector<T> result;
			result.resize(a.size());

			sort(a.begin(), a.end());
			sort(b.begin(), b.end());
			auto retEndPos = std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), result.begin());
			result.resize(retEndPos - result.begin());
			return result;
		}
		template<class T>
		std::vector<T> operator || (std::vector<T>a, std::vector<T> b)
		{
			using namespace std;
			std::vector<T> result;
			result.resize(a.size() + b.size());

			sort(a.begin(), a.end());
			sort(b.begin(), b.end());
			auto retEndPos = std::set_union(a.begin(), a.end(), b.begin(), b.end(), result.begin());
			result.resize(retEndPos - result.begin());
			return result;
		}
		template<class T>
		std::vector<T> operator - (std::vector<T> a, std::vector<T> b)
		{
			using namespace std;
			std::vector<T> result;
			result.resize(a.size());

			sort(a.begin(), a.end());
			sort(b.begin(), b.end());
			auto retEndPos = std::set_difference(a.begin(), a.end(), b.begin(), b.end(), result.begin());
			result.resize(retEndPos - result.begin());
			return result;
		}

		template<typename K, typename V>
		class JE_ThreadSafe_Map
		{
			std::map<K, V>__data;
			
		public:
			SharedMutex  __dataLock;
			std::map<K, V> getData()
			{
				std::lock_guard<SharedMutex> L_2(__dataLock);
				return __data;
			}
			inline Size size()
			{
				return __data.size();
			}
			template<typename ...T>
			JE_ThreadSafe_Map(T ... v) :__data(v...)
			{
			}
			JE_ThreadSafe_Map(const JE_ThreadSafe_Map<K, V>& _base)
			{
				SharedLock<SharedMutex> L_1(((JE_ThreadSafe_Map<K, V>&)_base).__dataLock);
				std::lock_guard<SharedMutex> L_2(__dataLock);
				__data = _base.__data;
			}
			inline V& operator [] (const K& __key)
			{
				if (find(__key))
				{
					SharedLock<SharedMutex> L_1(__dataLock);
					return __data[__key];
				}
				else
				{
					std::lock_guard<SharedMutex> L_2(__dataLock);
					return __data[__key];
				}
				return __data[__key];
			}
			inline void erase(const K& __key)
			{
				if (find(__key))
				{
					std::lock_guard<SharedMutex> L_1(__dataLock);

					__data.erase(__key);

				}
			}
			inline bool find(const K& __key)
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data.find(__key) != __data.end();
			}
			inline JE_ThreadSafe_Map& operator =(const JE_ThreadSafe_Map<K, V>& _base)
			{
				SharedLock<SharedMutex> L_1(((JE_ThreadSafe_Map<K, V>&)_base).__dataLock);
				std::lock_guard<SharedMutex> L_2(__dataLock);
				__data = _base.__data;
				return *this;
			}
			inline auto begin()
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data.begin();
			}
			inline auto end()
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data.end();
			}
			inline void clear()
			{
				std::lock_guard<SharedMutex> L_2(__dataLock);
				__data.clear();
			}
		};
		template< typename V>
		class JE_ThreadSafe_Vector
		{
			std::vector<V>__data;
			SharedMutex  __dataLock;
		public:
			template<typename ...T>
			JE_ThreadSafe_Vector(T ... v) :__data(v...)
			{
			}
			JE_ThreadSafe_Vector(const JE_ThreadSafe_Vector<V>& _base)
			{
				SharedLock<SharedMutex> L_1(((JE_ThreadSafe_Vector<V>&)_base).__dataLock);
				std::lock_guard<SharedMutex> L_2(__dataLock);
				__data = _base.__data;
			}
			inline V& operator [] (Size __key)
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data[__key];
				return __data[__key];
			}
			inline void erase(const V& __key)
			{
				if (find(__key))
				{
					std::lock_guard<SharedMutex> L_1(__dataLock);

					__data.erase(std::find(__data.begin(), __data.end(), __key));

				}
			}
			inline bool find(const V& __key)
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return std::find(__data.begin(), __data.end(), __key) != __data.end();
			}
			inline JE_ThreadSafe_Vector& operator =(const JE_ThreadSafe_Vector<V>& _base)
			{
				SharedLock<SharedMutex> L_1(((JE_ThreadSafe_Vector<V>&)_base).__dataLock);
				std::lock_guard<SharedMutex> L_2(__dataLock);
				__data = _base.__data;
				return *this;
			}
			inline auto begin()
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data.begin();
			}
			inline std::vector<V> getSimpleVector()
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data;
			}
			inline auto end()
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data.end();
			}
			inline void clear()
			{
				std::lock_guard<SharedMutex> L_2(__dataLock);
				__data.clear();
			}
			operator std::vector<V>()
			{
				SharedLock<SharedMutex> L_1(__dataLock);
				return __data;
			}
			V* push_back(const V& v)
			{
				std::lock_guard<SharedMutex> L_2(__dataLock);
				__data.push_back(v);
				return &*(__data.end() - 1);
			}
			inline Size size()
			{
				return __data.size();
			}

		};

		template<typename T>
		class JE_ThreadSafe_Queue
		{
			std::queue<T> _data;
			Lock __mutex;
		public:
			T& top()
			{
				std::lock_guard<Lock> L_2(__mutex);
				auto& a = _data.front();
				//
				return a;
			}
			void pop()
			{
				std::lock_guard<Lock> L_2(__mutex);
				_data.pop();
			}
			void push(const T& d)
			{
				std::lock_guard<Lock> L_2(__mutex);
				_data.push(d);
			}
			bool empty()
			{
				std::lock_guard<Lock> L_2(__mutex);
				return _data.empty();
			}
			void clear()
			{
				while (!empty())
					top();
			}
		};

		//线程安全的Map,使用一个索引类型来找到储存类型（类型）
		template<typename K, typename V>
		using Map = JE_ThreadSafe_Map<K, V>;

		//线程安全的动态数组（类型）
		template< typename V>
		using ThreadSafeVector = JE_ThreadSafe_Vector< V>;

		//字符串类型（类型）
		using String = std::string;

		//字符串的流类型（类型）
		using StringStream = std::stringstream;

		//导入文件流类型（类型）
		using InFileStream = std::ifstream;

		//导出文件流类型（类型）
		using OutFileStream = std::ofstream;

		//导入流类型（类型）
		using InStream = std::istream;

		//导出流类型（类型）
		using OutStream = std::ostream;

		//配对类型，可将两个对象或变量并为一组（类型）
		template<typename K, typename V>
		using Pair = std::pair<K, V>;

		//异常类型，向外抛出一个字符串常量作为异常信息（类型）
		class Exception
		{
			String err;
		public:
			Exception(const String& e)
			{
				err = e;
			}
			virtual String what()
			{
				return err;
			}
		};

		//非线程安全的动态数组（类型）
		template<typename V>
		using Vector = std::vector<V>;

		//线程安全的队列（类型）
		template<typename V>
		using Queue = JE_ThreadSafe_Queue< V>;

		//锁的保护装置（类型）
		template<typename V>
		using Lockground = std::lock_guard<V>;

		//布尔类型，表示真或假（类型）
		using Bool = bool;

		//#define __JELockit(D,X)\
		//ecs::Type::Lockground<ecs::Type::Lock> JE_R_KW_LocalL_##D (X)
		//#define _JELockit(D,X)\
		//		__JELockit(D,X)
		//#define JELockit(X)\
		//			__JELockit( __LINE__ , X)
		//

		//哈希函数，获取类型T的类型哈希值（编译期常量函数）
		template<typename T>
		inline static constexpr const Size Typehash()
		{
			return typeid(T).hash_code();
		}

		//与时间相关的常数和类型在此命名空间（命名空间）
		namespace Time
		{

			//高精度时钟（类型）
			using Clock = std::chrono::high_resolution_clock;

			//时间段（类型）
			using Duration = std::chrono::duration<ecs::Type::LongDouble, std::nano>;

			//时间点（类型）
			using TimePoint = std::chrono::time_point<Clock, Duration>;

			//一秒（常量）
			inline const auto oneSecond = std::chrono::seconds(1);

			//核心的启动时间（常量）
			inline const static TimePoint startTime = Clock::now();

			//获取当前的时间，返回类型是ecs::Type::LongDouble，单位是秒（函数/方法）
			inline static ecs::Type::LongDouble Now()
			{
				return  ((ecs::Type::LongDouble)((Clock::now().time_since_epoch().count() - startTime.time_since_epoch().count()) * Clock::period::num))
					/ ((ecs::Type::LongDouble)Clock::period::den);
			}

		}

		template<typename T>
		String ToString(const T& t)
		{
			StringStream A;
			String R;
			A << (T&)t;
			A >> R;
			return R;

		}
		template<typename T>
		T Parse(const String& t)
		{
			StringStream A;
			T R;
			A << t;
			A >> R;
			return R;

		}

	}


	//环境支持库，与平台相关的代码在此定义，同时支持模块间交互等（命名空间）
	namespace Environment
	{
#ifdef _WIN32
		inline HMODULE JEMOUDLEHWND(int V)
		{
#ifdef JOYENGINE_DLL_MODE
			HMODULE hModule = 0;
			GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (PCTSTR)JEMOUDLEHWND, &hModule);
			return hModule;
#else
			return GetModuleHandle(NULL);
#endif 

		}
#endif 

#ifdef _WIN32
#ifdef UNICODE
		inline ecs::Type::String GetProgramDir()
		{
			wchar_t exeFullPath[MAX_PATH]; // Full path   
			ecs::Type::String strPath = "";

			GetModuleFileName(NULL, exeFullPath, MAX_PATH);
			char CharString[MAX_PATH];
			size_t convertedChars = 0;
			wcstombs_s(&convertedChars, CharString, MAX_PATH, exeFullPath, _TRUNCATE);

			strPath = (ecs::Type::String)CharString;    // Get full path of the file   

			ecs::Type::Size pos = strPath.find_last_of('\\', strPath.length());
			return strPath.substr(0, pos) + "\\";  // Return the directory without the file name   
		}
#else
		inline ecs::Type::String GetProgramDir()
		{
			char exeFullPath[MAX_PATH]; // Full path   
			ecs::Type::String strPath = "";

			GetModuleFileName(NULL, exeFullPath, MAX_PATH);
			strPath = (ecs::Type::String)exeFullPath;    // Get full path of the file   

			ecs::Type::Size pos = strPath.find_last_of('\\', strPath.length());
			return strPath.substr(0, pos) + "\\";  // Return the directory without the file name   
		}
#endif

#else
		inline ecs::Type::String GetProgramDir()
		{
			char buf[512];
			int count;
			count = readlink("/proc/self/exe", buf, 512);
			if (count < 0 || count >= 512)
			{
				return"";
			}
			buf[count] = '\0';
			for (int size = count; size >= 0; size--)
			{
				if (buf[size] == '/' || buf[size] == '\\')
				{
					buf[size + 1] = 0;
					break;
				}
			}
			return buf;
		}


#endif


		namespace __CORE__
		{

			void StaticStartCall();

#ifdef __ECS_RUNTIME_CORE

			extern "C"
			{
				inline static ecs::Type::Map<ecs::Type::String, void*>SharedVariableList;
				DLL_EXPORT inline void* ____ECS_CORE_SHAREDVARIBALE_SHAREDOUT(const char* varname, void* ptrn)
				{
					return SharedVariableList[varname] = ptrn;
				}
				DLL_EXPORT inline void* ____ECS_CORE_SHAREDVARIBALE_SHAREDGET(const char* varname)
				{
					return SharedVariableList[varname];
				}
				DLL_EXPORT inline ecs::Type::Map<ecs::Type::String, void*>* ____ECS_CORE_SHAREDVARIBALE_SHAREDLIST()
				{
					return &SharedVariableList;
				}
				DLL_EXPORT inline bool ____ECS_CORE_MODULE_LOADMODULE(const char* libPath);
			}
#else
			extern "C"
			{
				void* ____ECS_CORE_SHAREDVARIBALE_SHAREDOUT(const char* varname, void* ptrn);
				void* ____ECS_CORE_SHAREDVARIBALE_SHAREDGET(const char* varname);
				bool ____ECS_CORE_MODULE_LOADMODULE(const char* libPath);
				ecs::Type::Map<ecs::Type::String, void*>* ____ECS_CORE_SHAREDVARIBALE_SHAREDLIST();
			}
#endif
		}

		namespace SpecialFunction
		{
			inline ecs::Type::String GetEndFileName(const ecs::Type::String& fname)
			{
				auto placeA = fname.find_last_of('\\');
				auto placeB = fname.find_last_of('/');
				size_t endPlace = 0;
				if (placeA < fname.size())
				{
					endPlace = placeA + 1;
				}
				if (placeB < fname.size() && placeB>placeA)
				{
					endPlace = placeB + 1;
				}

				return fname.substr(endPlace);
			}
		}

#define ___Macro_AutoAPIName(LN,FN)  ecs::Type::String("AutoAPIName_")+::ecs::Environment::SpecialFunction::GetEndFileName(FN)+"_"+#LN
#define __Macro_AutoAPIName(LN,FN) ___Macro_AutoAPIName(LN,FN)
#define AutoAPIName __Macro_AutoAPIName(__LINE__,__FILE__)

#define SharedDefineVar(...)ecs::Environment::Module::SharedVariable::SharedDefine<##__VA_ARGS__##>(AutoAPIName)


		class Module
		{

		public:
			class SharedVariable
			{
			public:

				template<typename T>
				static T& SharedOut(T& Var, const ecs::Type::String& name)
				{
#ifdef _WIN32
					static auto _MD_SHAREDOUT_FUNC = ((void* (*)(const char*, void*))
						GetProcAddress(JEMOUDLEHWND(NULL), "____ECS_CORE_SHAREDVARIBALE_SHAREDOUT")
						);
					return *(T*)_MD_SHAREDOUT_FUNC(name.data(), &Var);

#else
#ifdef __linux__
					return *(T*)ecs::Environment::__CORE__::____ECS_CORE_SHAREDVARIBALE_SHAREDOUT(name.data(), &Var);
#endif
#endif					
				}

#ifdef _WIN32

				template<typename T>
				static T& SharedDefine(const ecs::Type::String& name)
				{
					static ecs::Type::Map<ecs::Type::String, void*>& _MD_SHAREDLIST = *((ecs::Type::Map<ecs::Type::String, void*> * (*)())GetProcAddress(JEMOUDLEHWND(NULL), "____ECS_CORE_SHAREDVARIBALE_SHAREDLIST"))();
					if (_MD_SHAREDLIST.find(name) == false)
					{
						_MD_SHAREDLIST[name] = new T;
					}
					return *((T*)_MD_SHAREDLIST[name]);
				}
				static bool IsDefine(const ecs::Type::String& name)
				{
					static ecs::Type::Map<ecs::Type::String, void*>& _MD_SHAREDLIST = *((ecs::Type::Map<ecs::Type::String, void*> * (*)())GetProcAddress(JEMOUDLEHWND(NULL), "____ECS_CORE_SHAREDVARIBALE_SHAREDLIST"))();
					return _MD_SHAREDLIST.find(name);
				}
#else
#ifdef __linux__
				template<typename T>
				static T& SharedDefine(const ecs::Type::String& name)
				{

					static auto& _MD_SHAREDLIST = *ecs::Environment::__CORE__::____ECS_CORE_SHAREDVARIBALE_SHAREDLIST();
					if (!_MD_SHAREDLIST.find(name))
					{
						_MD_SHAREDLIST[name] = new T;
					}
					return *((T*)_MD_SHAREDLIST[name]);

				}

				static bool IsDefine(const ecs::Type::String& name)
				{
					static auto& _MD_SHAREDLIST = *ecs::Environment::__CORE__::____ECS_CORE_SHAREDVARIBALE_SHAREDLIST();
					return _MD_SHAREDLIST.find(name);
				}
#endif
#endif		


				template<typename T>
				static T& SharedOutConst(T Var, const ecs::Type::String& name)
				{
#ifdef _WIN32
					auto Ptr = new T(Var);
					static auto _MD_SHAREDOUT_FUNC = ((void* (*)(const char*, void*))
						GetProcAddress(JEMOUDLEHWND(NULL), "____ECS_CORE_SHAREDVARIBALE_SHAREDOUT")
						);
					return *(T*)_MD_SHAREDOUT_FUNC(name.data(), Ptr);

#else
#ifdef __linux__
					auto Ptr = new T(Var);
					return *(T*)ecs::Environment::__CORE__::____ECS_CORE_SHAREDVARIBALE_SHAREDOUT(name.data(), Ptr);
#endif
#endif					
				}


				template<typename T>
				static T& SharedGet(const ecs::Type::String& name)
				{
#ifdef _WIN32
					static auto _MD_SHAREDOUT_FUNC = ((void* (*)(const char*))
						GetProcAddress(JEMOUDLEHWND(NULL), "____ECS_CORE_SHAREDVARIBALE_SHAREDGET")
						);
					return *(T*)_MD_SHAREDOUT_FUNC(name.data());
#else
#ifdef __linux__
					return *(T*)ecs::Environment::__CORE__::____ECS_CORE_SHAREDVARIBALE_SHAREDGET(name.data());
#endif
#endif					
				}



			};
			Module(const ecs::Type::String& LibPath)
			{
#ifdef _WIN32
				static auto LoadModuleFunc = ((void(*)(const char*))
					GetProcAddress(JEMOUDLEHWND(NULL), "____ECS_CORE_MODULE_LOADMODULE")
					);
				LoadModuleFunc((LibPath).data());

#else
#ifdef __linux__
				ecs::Environment::__CORE__::____ECS_CORE_MODULE_LOADMODULE((LibPath).data()
				);
#endif
#endif		
			}
		};

		namespace IO
		{

			class Color
			{
#ifdef _WIN32
				static void SetColor(unsigned short ForeColor, unsigned short BackGroundColor)
				{
					HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
					SetConsoleTextAttribute(hCon, (ForeColor % 16) | (BackGroundColor % 16 * 16));
				}
#endif
			public:
#ifdef _WIN32
				static const int DefaultFrontColor = 7;
				static const int DefaultBackColor = 0;
				enum FrontColor
				{
					/*
					0 = 黑色       8 = 灰色
				1 = 蓝色       9 = 淡蓝色
				2 = 绿色       A = 淡绿色
				3 = 浅绿色     B = 淡浅绿色
				4 = 红色       C = 淡红色
				5 = 紫色       D = 淡紫色
				6 = 黄色       E = 淡黄色
				7 = 白色       F = 亮白色
				*/
					Black, Blue, Green, Aqua, Red, Purple,
					Yellow, White, Gray, LightBlue, LightGreen, LightAqua,
					LightRed, LightPurple, LightYellow, LightWhite
				};
				enum BackColor
				{
					/*
					0 = 黑色       8 = 灰色
				1 = 蓝色       9 = 淡蓝色
				2 = 绿色       A = 淡绿色
				3 = 浅绿色     B = 淡浅绿色
				4 = 红色       C = 淡红色
				5 = 紫色       D = 淡紫色
				6 = 黄色       E = 淡黄色
				7 = 白色       F = 亮白色
				*/
					BacBlack, BacBlue, BacGreen, BacAqua, BacRed, BacPurple,
					BacYellow, BacWhite, BacGray, BacLightBlue, BacLightGreen, BacLightAqua,
					BacLightRed, BacLightPurple, BacLightYellow, BacLightWhite
				};
#else
#ifdef __linux__
				/*
				30:黑
			31:红
			32:绿
			33:黄
			34:蓝色
			35:紫色
			36:深绿
			37:白色
			38 打开下划线,设置默认前景色
			39 关闭下划线,设置默认前景色
			40 黑色背景
			41 红色背景
			42 绿色背景
			43 棕色背景
			44 蓝色背景
			45 品红背景
			46 孔雀蓝背景
			47 白色背景 */
				static const int DefaultFrontColor = 37;
				static const int DefaultBackColor = 40;
				enum FrontColor
				{
					Black = 30, Red = 31, Green = 32, Yellow = 33, Blue = 34, Purple = 35, Aqua = 36, White = 37,
					Gray = 90, LightRed = 91, LightGreen = 92, LightYellow = 93, LightBlue = 94, LightPurple = 95, LightAqua = 96, LightWhite = 97
				};
				enum BackColor
				{
					BacBlack = 40, BacRed = 41, BacGreen = 42, BacYellow = 43, BacBlue = 44, BacPurple = 45, BacAqua = 46, BacWhite = 47,
					BacGray = 100, BacightRed = 101, BacLightGreen = 102, BacLightYellow = 103, BacLightBlue = 104, BacLightPurple = 105, BacLightAqua = 106, BacLightWhite = 107
				};
#endif
#endif

				static ecs::Type::String setColor(unsigned short ForeColor = DefaultFrontColor, unsigned short BackGroundColor = DefaultBackColor)
				{
#ifdef _WIN32
					SetColor(ForeColor, BackGroundColor);
					return "";
#else
#ifdef __linux__
					ecs::Type::StringStream fCstream;
					fCstream << ForeColor;
					ecs::Type::StringStream bCstream;
					bCstream << BackGroundColor;

					ecs::Type::String fCstring;
					ecs::Type::String bCstring;

					fCstream >> fCstring;
					bCstream >> bCstring;

					return "\033[" + fCstring + "m" + "\033[" + bCstring + "m";
#endif
#endif
				}
			};

			inline static std::istream& Input = std::cin;
			inline static std::ostream& Output = std::cout;
			inline static std::ostream& Errput = std::cerr;

		}

		namespace StartUp
		{
			inline static int& Argc = Module::SharedVariable::SharedDefine<int>("____ECS_CORE_ARGC");
			inline static char**& Argv = Module::SharedVariable::SharedDefine<char** >("____ECS_CORE_ARGV");
			inline static ecs::Type::Vector<ecs::Type::String>& Args =
				Module::SharedVariable::SharedDefine<ecs::Type::Vector<ecs::Type::String> >(AutoAPIName);

			inline ecs::Type::String GetArgs(const ecs::Type::String& cmds)
			{
				for (auto& arg : Args)
				{
					if (arg != "" && arg[0] == '-')
					{
						if (arg.substr(1) == cmds || arg.substr(1, arg.find(':') - 1) == cmds)
						{
							if (arg.find(':') < arg.size())
							{
								return arg.substr(arg.find(':') + 1);
							}
							return arg.substr(1);
						}
					}
				}
				return "null";
			}
		};
		inline void __CORE__::StaticStartCall()
		{
			auto& STIP = ecs::Environment::Module::SharedVariable::SharedDefine<ecs::Type::Vector<void(*)()>>("____ECS_CORE_STATICSTARTLIST_STIP");
			for (auto Fp : STIP)
			{
				//ecs::Environment::IO::Output << Fp << std::endl;
				Fp();
			}
			STIP.clear();
		}


		inline void exit(int _exn = 0)
		{
			::_exit(_exn);
		}

		inline void clear()
		{
#ifdef _WIN32
			system("cls");
#else
#ifdef __linux__
			system("clear");
#endif
#endif
		}

		inline void pause()
		{
#ifdef _WIN32
			system("pause");

#else
#ifdef __linux__
			ecs::Environment::IO::Output << "Push enter continue." << std::endl;
			getchar();
#endif
#endif
		}

		inline void (*&showConsole)(bool) =
			ecs::Environment::Module::SharedVariable::SharedDefine<void (*)(bool)>(AutoAPIName);

		inline bool& GUIShowStage
			= ecs::Environment::Module::SharedVariable::SharedDefine<bool>(AutoAPIName);

#ifdef __ECS_RUNTIME_CORE
		inline void __ShowConsole(bool state)
		{
			GUIShowStage = state;
#ifdef _WIN32

			constexpr size_t MY_BUFSIZE = 1024;
			// Buffer size for console window titles.

#ifdef UNICODE
			HWND hwndFound;         // This is what is returned to the caller.
			wchar_t pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
			// WindowTitle.
			wchar_t pszOldWindowTitle[MY_BUFSIZE]; // Contains original
			// WindowTitle.
			// Fetch current window title.
			GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
			// Format a "unique" NewWindowTitle.
			wsprintf(pszNewWindowTitle, L"%d/%d",
				GetTickCount(),
				GetCurrentProcessId());
			// Change current window title.
			SetConsoleTitle(pszNewWindowTitle);
			// Ensure window title has been updated.
			Sleep(40);
			// Look for NewWindowTitle.
			hwndFound = FindWindow(NULL, pszNewWindowTitle);
			// Restore original window title.
			SetConsoleTitle(pszOldWindowTitle);
#else
			HWND hwndFound;         // This is what is returned to the caller.
			char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
			// WindowTitle.
			char pszOldWindowTitle[MY_BUFSIZE]; // Contains original
			// WindowTitle.
			// Fetch current window title.
			GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
			// Format a "unique" NewWindowTitle.
			wsprintf(pszNewWindowTitle, "%d/%d",
				GetTickCount(),
				GetCurrentProcessId());
			// Change current window title.
			SetConsoleTitle(pszNewWindowTitle);
			// Ensure window title has been updated.
			Sleep(40);
			// Look for NewWindowTitle.
			hwndFound = FindWindow(NULL, pszNewWindowTitle);
			// Restore original window title.
			SetConsoleTitle(pszOldWindowTitle);
#endif


			ShowWindow(hwndFound, state);
#else
			//其他编译环境暂未实现
#endif
		}

#endif

		inline void AssertMessageBox(const ecs::Type::String& emcMsg)
		{
#ifdef _WIN32
#ifdef UNICODE

			std::wstring result;

			//获取缓冲区大小，并申请空间，缓冲区大小按字符计算  

			int len = MultiByteToWideChar(CP_ACP, 0, emcMsg.c_str(), (int)emcMsg.size(), NULL, 0);

			TCHAR* buffer = new TCHAR[len + 1];

			//多字节编码转换成宽字节编码  

			MultiByteToWideChar(CP_ACP, 0, emcMsg.c_str(), (int)emcMsg.size(), buffer, len);

			buffer[len] = '\0';             //添加字符串结尾  

			//删除缓冲区并返回值  

			result.append(buffer);

			delete[] buffer;

			MessageBox(NULL, result.data(), L"JoyEngineAWK", 0);
#else
			MessageBox(NULL, emcMsg.data(), "JoyEngineAWK", MB_ICONERROR);
#endif
#else
			//其他编译环境暂未实现
#endif
			std::abort();
		}
		namespace Path
		{
			//public:
			inline static ecs::Type::String& ExeFilePath = ecs::Environment::Module::SharedVariable::SharedDefine<ecs::Type::String>("___ECS_CORE_EXEFILEPATH");
		};//GetProgramDir();

#ifdef __ECS_RUNTIME_CORE
		namespace __CORE__
		{
			extern "C"
			{
				DLL_EXPORT inline bool ____ECS_CORE_MODULE_LOADMODULE(const char* libPath)
				{
					static ecs::Type::ThreadSafeVector<ecs::Type::String>& PreSaveCommand = ecs::Environment::Module::SharedVariable::SharedDefine< ecs::Type::ThreadSafeVector<ecs::Type::String>>("SCENE_SAVER_PRESAVECOMMAND");
#ifdef _WIN32			
					//*(ecs::Type::Int*)____ECS_CORE_SHAREDVARIBALE_SHAREDGET("____ECS_CORE_MODULE_VERSION_SIGN") = 0;
					HINSTANCE Modnum = LoadLibraryExA((ecs::Environment::Path::ExeFilePath + libPath).data(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
					if (Modnum != NULL)
					{
						auto VerFunc = (ecs::Type::UInt*)____ECS_CORE_SHAREDVARIBALE_SHAREDGET("____ECS_CORE_MODULE_VERSION_SIGN");//____ECS_CORE_MODULE_VERSION_SIGN

						if (VerFunc != nullptr)
						{
							if ((*VerFunc) / 0x100 == ECS_CORE_VERSION / 0x100)
							{

								StaticStartCall();
								auto MainFunc = (ecs::Type::Int(*)(void))GetProcAddress(Modnum, "ecs_entry");
								if (MainFunc != nullptr)
								{
									if (MainFunc())
										PreSaveCommand.push_back("loadmodule " + ecs::Type::String(libPath));
								}
								*VerFunc = 0;
								return true;
							}
							else
							{
								ecs::Environment::showConsole(true);
								IO::Output << "您正在挂载核心版本为" << std::hex << (*VerFunc) << "的模块，但此版本的核心模块与当前版本（" << std::hex << ECS_CORE_VERSION << ")不兼容\a" << std::dec << std::endl;;
								pause();
								exit();
								StaticStartCall();
								auto MainFunc = (ecs::Type::Int(*)(void))GetProcAddress(Modnum, "ecs_entry");
								if (MainFunc != nullptr)
								{
									if (MainFunc())
										PreSaveCommand.push_back("loadmodule " + ecs::Type::String(libPath));
									*VerFunc = 0;
									return true;
								}
								FreeLibrary(Modnum);
								*VerFunc = 0;
								return false;

							}
						}

						FreeLibrary(Modnum);
						ecs::Environment::AssertMessageBox(Type::String("在载入库：") + libPath + "时发生错误："
							+ "没有找到基准版本标识函数，这个模块是一个非JoyEngine模块"
						);
						return false;
					}
					ecs::Environment::AssertMessageBox(Type::String("在载入库：") + libPath + "时发生错误："
						+ "这个模块没有被找到。"
					);
					return false;
#else
#ifdef __linux__
					//*(ecs::Type::Int*)____ECS_CORE_SHAREDVARIBALE_SHAREDGET("____ECS_CORE_MODULE_VERSION_SIGN") = 0;
					auto Modnum = dlopen((ecs::Environment::Path::ExeFilePath + libPath).data(), RTLD_LAZY);
					if (Modnum != NULL)
					{
						auto VerFunc = (ecs::Type::Int*)____ECS_CORE_SHAREDVARIBALE_SHAREDGET("____ECS_CORE_MODULE_VERSION_SIGN");//____ECS_CORE_MODULE_VERSION_SIGN
						if (VerFunc != nullptr)
						{

							switch (*VerFunc)
							{
							case (int)0xD1000000:
							{
								StaticStartCall();
								auto MainFunc = (ecs::Type::Int(*)(void))dlsym(Modnum, "ecs_entry");
								if (MainFunc != nullptr)
									if (MainFunc())
										PreSaveCommand.push_back("loadmodule " + ecs::Type::String(libPath));
								*VerFunc = 0;
								return true;
							}
							default:
								//ecs::Environment::IO::Output << "Undefined version." << std::endl;
								StaticStartCall();
								auto MainFunc = (ecs::Type::Int(*)(void))dlsym(Modnum, "ecs_entry");
								if (MainFunc != nullptr)
								{
									if (MainFunc())
										PreSaveCommand.push_back("loadmodule " + ecs::Type::String(libPath));
									*VerFunc = 0;
									return true;
								}
								dlclose(Modnum);
								*VerFunc = 0;
								return false;

							}
						}
						//ecs::Environment::IO::Output << "Version function not found." << std::endl;

						dlclose(Modnum);
						return false;
					}
					std::cout << dlerror() << std::endl;
					return false;
#endif
#endif		
				}
			}
		}
#endif

		}
	}

	
